//*********************************************************
//
//    Copyright (c) Microsoft. All rights reserved.
//    This code is licensed under the Apache License, Version 2.0.
//    THIS CODE IS PROVIDED *AS IS* WITHOUT WARRANTY OF
//    ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING ANY
//    IMPLIED WARRANTIES OF FITNESS FOR A PARTICULAR
//    PURPOSE, MERCHANTABILITY, OR NON-INFRINGEMENT.
//
//*********************************************************

using System;
using System.Collections.Generic;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using C = config;

namespace DataLayerBuilder
{
    public partial class DataGen
    {
        void SaveScript(string action, string name, StringBuilder script)
        {
            string dbOutputFolder = Path.Combine(outputFolder, "..\\dbgen.sql");

            // Create the output folder
            if (!Directory.Exists(dbOutputFolder))
                Directory.CreateDirectory(dbOutputFolder);

            // Save the script to disk
            string filePath = Path.Combine(dbOutputFolder, string.Format("create_{0}_{1}.sql",
                action, name));

            using (StreamWriter sw = new StreamWriter(filePath))
            {
                sw.Write(script.ToString());
            }
        }

        void GenerateDataStore(List<ObjectDef> objList, List<RelationDef> relList)
        {
            //
            // Objects
            //
            foreach (ObjectDef obj in objList)
            {
                Log(0, "Processing '{0}'...", obj.Name);

                // Create the table
                StringBuilder createSQL = new StringBuilder(Properties.Resource1.table_create);
                StringBuilder fieldSQL = new StringBuilder();
                StringBuilder refSQL = new StringBuilder();

                if (obj.BaseClass == ParentClasses.NamedObject.ToString())
                {
                    FieldDef f = new FieldDef("Name", config.datatype.@string, "Name", true);
                    fieldSQL.AppendLine(f.SQLCreate);
                }

                foreach (FieldDef f in obj.Fields)
                {
                    try
                    {
                        fieldSQL.AppendLine(f.SQLCreate);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }
                foreach (RefDef r in obj.References)
                {
                    try
                    {
                        fieldSQL.AppendLine(r.SQLCreate);
                        refSQL.AppendLine(r.SQLRelation);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }
                foreach (FieldDef f in obj.Enums)
                {
                    try
                    {
                        fieldSQL.AppendLine(f.SQLCreate);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }

                // Add to the SQL statement
                createSQL.Replace("%FIELD_DEFS%\r\n", fieldSQL.ToString());

                // Update all object references
                createSQL.Replace("%OBJECT%", obj.Name);
                refSQL.Replace("%OBJECT%", obj.Name);

                //Console.WriteLine("-- ------------------------------------------");
                //Console.WriteLine("-- Create object: {0}", obj.Name);
                //Console.WriteLine("-- ------------------------------------------");
                //Console.WriteLine(createSQL.ToString());
                //Console.WriteLine(refSQL.ToString());
                //Console.WriteLine("-- ------------------------------------------");

                SaveScript("table_P1", obj.Name, createSQL);
                SaveScript("table_P2", obj.Name, refSQL);
            }

            //
            // Relationships
            //
            foreach (RelationDef rel in relList)
            {
                Log(0, "Processing '{0}' <--> '{1}'...", rel.One, rel.Two);

                string oneName = rel.One;
                string twoName = rel.Two;

                if (oneName == twoName)
                {
                    // Self relationship
                    oneName = string.Format("{0}_1", rel.One);
                    twoName = string.Format("{0}_2", rel.Two);
                }

                // Create the table
                StringBuilder createSQL = new StringBuilder(Properties.Resource1.relation_create);
                createSQL.Replace("%ONE%", rel.One);
                createSQL.Replace("%ONE_NAME%", oneName);
                createSQL.Replace("%TWO%", rel.Two);
                createSQL.Replace("%TWO_NAME%", twoName);

                StringBuilder fieldSQL = new StringBuilder();
                foreach (FieldDef f in rel.Fields)
                {
                    try
                    {
                        fieldSQL.AppendLine(f.SQLCreate);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }
                foreach (FieldDef f in rel.Enums)
                {
                    try
                    {
                        fieldSQL.AppendLine(f.SQLCreate);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }

                createSQL.Replace("%OBJECT%", rel.TableName);
                createSQL.Replace("%FIELD_DEFS%\r\n", fieldSQL.ToString());

                //Console.WriteLine("-- ------------------------------------------");
                //Console.WriteLine("-- Create relation: {0}", rel.TableName);
                //Console.WriteLine("-- ------------------------------------------");
                //Console.WriteLine(createSQL.ToString());
                //Console.WriteLine("-- ------------------------------------------");

                SaveScript("relation", rel.TableName, createSQL);
            }

            //
            // Views
            //
            foreach (ObjectDef obj in objList)
            {
                Log(0, "Processing view '{0}'", obj.Name);

                StringBuilder fieldList = new StringBuilder();

                if (obj.BaseClass == ParentClasses.NamedObject.ToString())
                {
                    FieldDef field = new FieldDef("Name", config.datatype.@string, "Name", true);

                    fieldList.AppendLine(string.Format("    [{0}],", field.SQLName));
                }

                foreach (FieldDef field in obj.Fields)
                {
                    if (!field.IsBLOB)
                        fieldList.AppendLine(string.Format("    [{0}],", field.SQLName));
                }
                foreach (FieldDef field in obj.Enums)
                {
                    if (!field.IsBLOB)
                        fieldList.AppendLine(string.Format("    [{0}],", field.SQLName));
                }
                foreach (RefDef field in obj.References)
                {
                    fieldList.AppendLine(string.Format("    [{0}],", field.SQLName));
                }

                StringBuilder countList = new StringBuilder();
                StringBuilder relFields = new StringBuilder();
                foreach (RelationDef rel in obj.Relations)
                {
                    if (rel.IsSelfRelation)
                    {
                        countList.AppendLine(string.Format("        LEFT OUTER JOIN [{0}_{2}Count] ON [{0}s].ID = [{0}_{2}Count].ID",
                            obj.Name, rel.Other(obj.Name), rel.OtherFieldName(RelationDef.RelationDirection.One)));
                        relFields.AppendLine(string.Format("    [{0}Count],", rel.OtherFieldName(RelationDef.RelationDirection.One)));
                    }
                    else
                    {
                        countList.AppendLine(string.Format("        LEFT OUTER JOIN [{0}_{1}Count] ON [{0}s].ID = [{0}_{1}Count].ID",
                            obj.Name, rel.Other(obj.Name), rel.Other(rel.One)));
                        relFields.AppendLine(string.Format("    [{0}Count],", rel.Other(obj.Name)));
                    }

                    if (rel.IsSelfRelation && rel.IsTwoWay)
                    {
                        countList.AppendLine(string.Format("        LEFT OUTER JOIN [{0}_{2}Count] ON [{0}s].ID = [{0}_{2}Count].ID",
                            obj.Name, rel.Other(obj.Name), rel.OtherFieldName(RelationDef.RelationDirection.Two)));
                        relFields.AppendLine(string.Format("    [{0}Count],", rel.OtherFieldName(RelationDef.RelationDirection.Two)));
                    }
                }

                foreach (RefDef myRef in obj.RevRef)
                {
                    countList.AppendLine(string.Format("        LEFT OUTER JOIN [{0}_{1}Count] ON [{0}s].ID = [{0}_{1}Count].ID",
                        obj.Name, myRef.RevName ?? myRef.Source.Name));
                    relFields.AppendLine(string.Format("    [{0}Count],", myRef.RevName ?? myRef.Source.Name));
                }

                string objViewName = string.Format("{0}_Base", obj.Name);
                StringBuilder viewSQL = new StringBuilder(Properties.Resource1.view_base);
                viewSQL.Replace("%OBJECT%", obj.Name);
                viewSQL.Replace("    %FIELD_LIST%\r\n", fieldList.ToString());
                viewSQL.Replace("        %REL_JOINS%\r\n", countList.ToString());
                viewSQL.Replace("    %REL_FIELDS%\r\n", relFields.ToString());


                //Console.WriteLine("-- ------------------------------------------");
                //Console.WriteLine("-- Create view: {0}_Base", objViewName);
                //Console.WriteLine("-- ------------------------------------------");
                //Console.WriteLine(viewSQL.ToString());
                //Console.WriteLine("-- ------------------------------------------");

                SaveScript("view_base", objViewName, viewSQL);
            }

            //
            // View counts
            //
            foreach (ObjectDef obj in objList)
            {
                Log(0, "Processing view count '{0}'", obj.Name);

                foreach (RelationDef rel in obj.Relations)
                {
                    string one;
                    string two;
                    string twoName;
                    string twoNameInv;
                    string oneName;
                    string objViewName;

                    if (rel.IsSelfRelation &&
                        rel.OneName != null && rel.TwoName != null &&
                        rel.OneName == rel.TwoName)
                    {
                        Console.WriteLine("FATAL: Relationship '{0}' defines a self-relationship and specifies the same field names as 'oneName' and 'twoName'", obj.Name);
                    }

                    if (rel.IsSelfRelation)
                    {
                        // First the going forward
                        one = obj.Name;
                        oneName = rel.OtherKeyName(RelationDef.RelationDirection.One);
                        two = rel.OtherFieldName(RelationDef.RelationDirection.One);
                        twoName = two;
                        twoNameInv = two;

                        objViewName = string.Format("{0}_{1}Count", one, twoName);
                    }
                    else
                    {
                        //Need to update the onename here to fix the view count
                        one = obj.Name;
                        two = rel.OtherObjectName(rel.One);

                        twoName = rel.OtherName2(one);
                        twoNameInv = rel.OtherName2(one);
                        oneName = rel.OtherObjectName(two);

                        objViewName = string.Format("{0}_{1}Count", one, twoName);
                    }

                    StringBuilder viewSQL = new StringBuilder(Properties.Resource1.view_count);

                    viewSQL.Replace("%OBJECT%", rel.TableName);
                    viewSQL.Replace("%ONE%", one);
                    viewSQL.Replace("%ONE_NAME%", oneName);
                    viewSQL.Replace("%TWO%", two);
                    viewSQL.Replace("%TWO_NAME%", twoName);
                    viewSQL.Replace("%TWO_NAME_INV%", twoNameInv);

                    //Console.WriteLine("-- ------------------------------------------");
                    //Console.WriteLine("-- Create view: {0}_Base", objViewName);
                    //Console.WriteLine("-- ------------------------------------------");
                    //Console.WriteLine(viewSQL.ToString());
                    //Console.WriteLine("-- ------------------------------------------");

                    SaveScript("view_count", objViewName, viewSQL);

                    // Generate a reverse Count Script if this is a version
                    // relation
                    if (rel.IsSelfRelation && rel.IsTwoWay)
                    {
                        viewSQL = new StringBuilder(Properties.Resource1.view_count);

                        // First the going forward
                        one = obj.Name;
                        oneName = rel.OtherKeyName(RelationDef.RelationDirection.Two);
                        two = rel.OtherFieldName(RelationDef.RelationDirection.Two);
                        twoName = two;
                        twoNameInv = two;

                        viewSQL.Replace("%OBJECT%", rel.TableName);
                        viewSQL.Replace("%ONE%", one);
                        viewSQL.Replace("%ONE_NAME%", oneName);
                        viewSQL.Replace("%TWO%", two);
                        viewSQL.Replace("%TWO_NAME%", twoName);
                        viewSQL.Replace("%TWO_NAME_INV%", twoNameInv);

                        objViewName = string.Format("{0}_{1}Count", one, twoName);

                        SaveScript("view_count", objViewName, viewSQL);
                    }
                }

                foreach (RefDef myRef in obj.RevRef)
                {
                    string one;
                    string two;
                    string field;
                    string key;

                    one = obj.Name;
                    two = myRef.Source.Name;
                    field = myRef.RevName ?? myRef.Source.Name;
                    key = myRef.StoreAs ?? myRef.Name;

                    string objViewName = string.Format("{0}_{1}Count", one, field);
                    StringBuilder viewSQL = new StringBuilder(Properties.Resource1.view_count_rev);

                    viewSQL.Replace("%OBJECT%", string.Format("{0}s", myRef.Source.Name));
                    viewSQL.Replace("%ONE%", one);
                    viewSQL.Replace("%TWO%", two);
                    viewSQL.Replace("%STORE%", field);
                    viewSQL.Replace("%KEY%", key);

                    //Console.WriteLine("-- ------------------------------------------");
                    //Console.WriteLine("-- Create view: {0}_Base", objViewName);
                    //Console.WriteLine("-- ------------------------------------------");
                    //Console.WriteLine(viewSQL.ToString());
                    //Console.WriteLine("-- ------------------------------------------");

                    SaveScript("view_count", objViewName, viewSQL);
                }
            }

            //
            // Stored procedures
            //
            foreach (ObjectDef obj in objList)
            {
                Log(0, "Processing SP add/delete/update/... '{0}'", obj.Name);

                bool hasName = false;
                StringBuilder spParamTypes = new StringBuilder();
                StringBuilder spParamList = new StringBuilder();
                StringBuilder spFieldList = new StringBuilder();
                StringBuilder spFieldAssign = new StringBuilder();
                StringBuilder spSearchClauses = new StringBuilder();

                if (obj.BaseClass == ParentClasses.NamedObject.ToString())
                {
                    FieldDef field = new FieldDef("Name", config.datatype.@string, "Name", true);

                    hasName |= (field.Name.Equals("Name", StringComparison.InvariantCultureIgnoreCase));
                    spParamTypes.AppendLine(string.Format("{0}", field.SQLSPType));
                    spFieldList.AppendLine(string.Format("            [{0}],", field.SQLName));
                    spParamList.AppendLine(string.Format("            @{0},", field.SQLName));
                    spFieldAssign.AppendLine(string.Format("            [{0}] = @{0},", field.SQLName));

                    if (field.SQLSearchClause != null)
                        spSearchClauses.AppendLine(field.SQLSearchClause);
                }

                foreach (FieldDef field in obj.Fields)
                {
                    try
                    {
                        hasName |= (field.Name.Equals("Name", StringComparison.InvariantCultureIgnoreCase));
                        spParamTypes.AppendLine(string.Format("{0}", field.SQLSPType));
                        spFieldList.AppendLine(string.Format("            [{0}],", field.SQLName));
                        spParamList.AppendLine(string.Format("            @{0},", field.SQLName));
                        spFieldAssign.AppendLine(string.Format("            [{0}] = @{0},", field.SQLName));

                        if (field.SQLSearchClause != null)
                            spSearchClauses.AppendLine(field.SQLSearchClause);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }
                foreach (FieldDef field in obj.Enums)
                {
                    try
                    {
                        hasName |= (field.Name.Equals("Name", StringComparison.InvariantCultureIgnoreCase));
                        spParamTypes.AppendLine(string.Format("{0}", field.SQLSPType));
                        spFieldList.AppendLine(string.Format("            [{0}],", field.SQLName));
                        spParamList.AppendLine(string.Format("            @{0},", field.SQLName));
                        spFieldAssign.AppendLine(string.Format("            [{0}] = @{0},", field.SQLName));

                        if (field.SQLSearchClause != null)
                            spSearchClauses.AppendLine(field.SQLSearchClause);
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }
                foreach (RefDef refs in obj.References)
                {
                    try
                    {
                        hasName |= (refs.Name.Equals("Name", StringComparison.InvariantCultureIgnoreCase));
                        spParamTypes.AppendLine(string.Format("{0}", refs.SQLSPType));
                        spFieldList.AppendLine(string.Format("            [{0}],", refs.SQLName));
                        spParamList.AppendLine(string.Format("            @{0},", refs.SQLName));
                        spFieldAssign.AppendLine(string.Format("            [{0}] = @{0},", refs.SQLName));
                    }
                    catch (FieldShouldBeSkipped)
                    {
                        /* No action needed */
                    }
                }

                StringBuilder spSQL = new StringBuilder(Properties.Resource1.sp_add);
                spSQL.Replace("%OBJECT%", obj.Name);
                spSQL.Replace("%SP_PARAM_TYPES%\r\n", spParamTypes.ToString());
                spSQL.Replace("            %SP_FIELDS%\r\n", spFieldList.ToString());
                spSQL.Replace("            %SP_PARAM_LIST%\r\n", spParamList.ToString());

                StringBuilder spDelSQL = new StringBuilder(Properties.Resource1.sp_delete);
                spDelSQL.Replace("%OBJECT%", obj.Name);

                StringBuilder spUpdSQL = new StringBuilder(Properties.Resource1.sp_update);
                spUpdSQL.Replace("%OBJECT%", obj.Name);
                spUpdSQL.Replace("%SP_PARAM_TYPES%\r\n", spParamTypes.ToString());
                spUpdSQL.Replace("            %FIELD_ASSIGN%\r\n", spFieldAssign.ToString());

                StringBuilder spSrchSQL = new StringBuilder(Properties.Resource1.sp_search);
                spSrchSQL.Replace("%OBJECT%", obj.Name);
                spSrchSQL.Replace("                    %TEXT_FIELDS_CLAUSE%\r\n", spSearchClauses.ToString());

                StringBuilder spGetSQL = new StringBuilder(
                    hasName ? Properties.Resource1.sp_get_name_ : Properties.Resource1.sp_get);
                spGetSQL.Replace("%OBJECT%", obj.Name);

                StringBuilder spGetByIDSQL = new StringBuilder(Properties.Resource1.sp_getbyid);
                spGetByIDSQL.Replace("%OBJECT%", obj.Name);

                SaveScript("sp_add", obj.Name, spSQL);
                SaveScript("sp_delete", obj.Name, spDelSQL);
                SaveScript("sp_update", obj.Name, spUpdSQL);
                SaveScript("sp_search", obj.Name, spSrchSQL);
                SaveScript("sp_get", obj.Name, spGetSQL);
                SaveScript("sp_getbyid", obj.Name, spGetByIDSQL);
            }

            //
            // Stored procedures (obj_*Count)
            //
            foreach (ObjectDef obj in objList)
            {
                Log(0, "Processing SP count '{0}'", obj.Name);

                foreach (RelationDef rel in obj.Relations)
                {
                    // Only generate One -> Two pass
                    if ((obj.Name != rel.One && !rel.IsTwoWay) && !rel.IsSelfRelation)
                        continue;

                    string one;
                    string two;

                    if (rel.IsSelfRelation)
                    {
                        one = obj.Name;
                        two = rel.OtherFieldName(RelationDef.RelationDirection.One);
                    }
                    else
                    {
                        one = obj.Name;
                        two = rel.OtherName2(obj.Name);
                    }

                    StringBuilder spCountSQL = new StringBuilder(Properties.Resource1.sp_count);
                    spCountSQL.Replace("%OBJECT%", one);
                    spCountSQL.Replace("%REL%", two);

                    SaveScript("sp_count", string.Format("{0}s_{1}Count", one, two), spCountSQL);

                    if (rel.IsSelfRelation && rel.IsTwoWay)
                    {
                        // Generate the reverse count
                        one = obj.Name;
                        two = rel.OtherFieldName(RelationDef.RelationDirection.Two);

                        spCountSQL = new StringBuilder(Properties.Resource1.sp_count);
                        spCountSQL.Replace("%OBJECT%", one);
                        spCountSQL.Replace("%REL%", two);

                        SaveScript("sp_count", string.Format("{0}s_{1}Count", one, two), spCountSQL);
                    }
                }

                foreach (RefDef myRef in obj.RevRef)
                {
                    string one;
                    string two;
                    string field;
                    string key;

                    one = obj.Name;
                    two = myRef.Source.Name;
                    field = myRef.RevName ?? myRef.Source.Name;
                    key = myRef.StoreAs ?? myRef.Name;

                    string objViewName = string.Format("{0}_{1}Count", one, field);
                    StringBuilder spCountSQL = new StringBuilder(Properties.Resource1.sp_count);

                    spCountSQL.Replace("%OBJECT%", one);
                    spCountSQL.Replace("%REL%", field);

                    SaveScript("rel_sp_count", objViewName, spCountSQL);
                }
            }

            //
            // Stored procedures (blob delete)
            //
            foreach (ObjectDef obj in objList)
            {
                foreach (FieldDef field in obj.Fields)
                {
                    if (field.IsBLOB)
                    {
                        // Generate stored procedure to delete chunks
                        string blobName = string.Format("{0}{1}Blob", obj.Name, field.Name);
                        StringBuilder spDelSQL = new StringBuilder(Properties.Resource1.rel_blob_delete);
                        spDelSQL.Replace("%BLOB_STORE%", blobName);
                        spDelSQL.Replace("%OBJECT%", obj.Name);

                        SaveScript("sp_delete", string.Format("{0}{1}s", obj.Name, blobName), spDelSQL);
                    }
                }
            }

            //
            // Stored procedures (Relation)
            //
            foreach (ObjectDef obj in objList)
            {
                Log(0, "Processing REL SP add/delete '{0}'", obj.Name);

                foreach (RelationDef rel in obj.Relations)
                {
                    // Only generate One -> Two pass
                    if (obj.Name != rel.One && !rel.IsTwoWay)
                        continue;

                    //string one = rel.OtherName(rel.One);
                    //string two = rel.OtherName(rel.Two);
                    string one = rel.One;
                    string two = rel.Two;
                    string twoObj = rel.ObjectClassName(rel.One);
                    string spAddName = string.Format("{0}{1}", one, twoObj);
                    string spDelName = string.Format("{0}{1}", one, twoObj);
                    string spUpdName = string.Format("{0}{1}", one, twoObj);

                    if (one == two)
                    {
                        // Self relationship
                        one = string.Format("{0}_1", one);
                        two = string.Format("{0}_2", two);
                    }

                    StringBuilder spParamTypes = new StringBuilder();
                    StringBuilder spParamList = new StringBuilder();
                    StringBuilder spFieldList = new StringBuilder();
                    StringBuilder spFieldAssign = new StringBuilder();

                    foreach (FieldDef field in rel.Fields)
                    {
                        try
                        {
                            spParamTypes.AppendLine(string.Format("{0}", field.SQLSPType));
                            spFieldList.AppendLine(string.Format("            [{0}],", field.SQLName));
                            spParamList.AppendLine(string.Format("            @{0},", field.SQLName));
                            spFieldAssign.AppendLine(string.Format("            [{0}] = @{0},", field.SQLName));
                        }
                        catch (FieldShouldBeSkipped)
                        {
                            /* No action needed */
                        }
                    }

                    foreach (EnumDef field in rel.Enums)
                    {
                        try
                        {
                            spParamTypes.AppendLine(string.Format("{0}", field.SQLSPType));
                            spFieldList.AppendLine(string.Format("            [{0}],", field.SQLName));
                            spParamList.AppendLine(string.Format("            @{0},", field.SQLName));
                            spFieldAssign.AppendLine(string.Format("            [{0}] = @{0},", field.SQLName));
                        }
                        catch (FieldShouldBeSkipped)
                        {
                            /* No action needed */
                        }
                    }

                    StringBuilder spAddSQL = new StringBuilder(Properties.Resource1.rel_sp_add);
                    spAddSQL.Replace("%OBJECT%", spAddName);
                    spAddSQL.Replace("%ONE%", one);
                    spAddSQL.Replace("%TWO_NAME%", two);
                    spAddSQL.Replace("%SP_PARAM_TYPES%\r\n", spParamTypes.ToString());
                    spAddSQL.Replace("            %SP_FIELDS%\r\n", spFieldList.ToString());
                    spAddSQL.Replace("            %SP_PARAM_LIST%\r\n", spParamList.ToString());

                    StringBuilder spDelSQL = new StringBuilder(Properties.Resource1.rel_sp_del);
                    spDelSQL.Replace("%OBJECT%", spAddName);
                    spDelSQL.Replace("%ONE%", one);
                    spDelSQL.Replace("%TWO_NAME%", two);

                    StringBuilder spUpdSQL = new StringBuilder(Properties.Resource1.rel_sp_upd);
                    spUpdSQL.Replace("%OBJECT%", spAddName);
                    spUpdSQL.Replace("%ONE%", one);
                    spUpdSQL.Replace("%TWO_NAME%", two);
                    spUpdSQL.Replace("%SP_PARAM_TYPES%\r\n", spParamTypes.ToString());
                    spUpdSQL.Replace("            %FIELD_ASSIGN%\r\n", spFieldAssign.ToString());

                    SaveScript("rel_sp_add", spAddName, spAddSQL);
                    SaveScript("rel_sp_delete", spDelName, spDelSQL);
                    SaveScript("rel_sp_update", spUpdName, spUpdSQL);
                }
            }

            //
            // Static Stored procedures.
            //
            Log(0, "Processing Static Stored procedures");

            // Create LOGIN.
            Log(0, "Create LOGIN");
            StringBuilder spCreateLogin = new StringBuilder(Properties.Resource1.createLogin);
            SaveScript("sp_static", "CreateLogin", spCreateLogin);

            // Create USER.
            Log(0, "Create USER");
            StringBuilder spCreateUser = new StringBuilder(Properties.Resource1.createUser);
            SaveScript("sp_static", "CreateUser", spCreateUser);
        }
    }
}
